home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / tcsh / dist / sh.parse.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-21  |  13.8 KB  |  707 lines

  1. /* $Header: /home/hyperion/mu/christos/src/sys/tcsh-6.01/RCS/sh.parse.c,v 3.5 1991/11/26 04:41:23 christos Exp $ */
  2. /*
  3.  * sh.parse.c: Interpret a list of tokens
  4.  */
  5. /*-
  6.  * Copyright (c) 1980, 1991 The Regents of the University of California.
  7.  * All rights reserved.
  8.  *
  9.  * Redistribution and use in source and binary forms, with or without
  10.  * modification, are permitted provided that the following conditions
  11.  * are met:
  12.  * 1. Redistributions of source code must retain the above copyright
  13.  *    notice, this list of conditions and the following disclaimer.
  14.  * 2. Redistributions in binary form must reproduce the above copyright
  15.  *    notice, this list of conditions and the following disclaimer in the
  16.  *    documentation and/or other materials provided with the distribution.
  17.  * 3. All advertising materials mentioning features or use of this software
  18.  *    must display the following acknowledgement:
  19.  *    This product includes software developed by the University of
  20.  *    California, Berkeley and its contributors.
  21.  * 4. Neither the name of the University nor the names of its contributors
  22.  *    may be used to endorse or promote products derived from this software
  23.  *    without specific prior written permission.
  24.  *
  25.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  26.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  27.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  28.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  29.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  30.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  31.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  32.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  33.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  34.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  35.  * SUCH DAMAGE.
  36.  */
  37. #include "sh.h"
  38.  
  39. RCSID("$Id: sh.parse.c,v 3.5 1991/11/26 04:41:23 christos Exp $")
  40.  
  41. /*
  42.  * C shell
  43.  */
  44. static    void         asyntax __P((struct wordent *, struct wordent *));
  45. static    void         asyn0      __P((struct wordent *, struct wordent *));
  46. static    void         asyn3     __P((struct wordent *, struct wordent *));
  47. static    struct wordent    *freenod __P((struct wordent *, struct wordent *));
  48. static    struct command    *syn0     __P((struct wordent *, struct wordent *, int));
  49. static    struct command    *syn1     __P((struct wordent *, struct wordent *, int));
  50. static    struct command    *syn1a     __P((struct wordent *, struct wordent *, int));
  51. static    struct command    *syn1b     __P((struct wordent *, struct wordent *, int));
  52. static    struct command    *syn2     __P((struct wordent *, struct wordent *, int));
  53. static    struct command    *syn3     __P((struct wordent *, struct wordent *, int));
  54.  
  55. #define ALEFT    51        /* max of 50 alias expansions     */
  56. #define HLEFT    11        /* max of 10 history expansions */
  57. /*
  58.  * Perform aliasing on the word list lex
  59.  * Do a (very rudimentary) parse to separate into commands.
  60.  * If word 0 of a command has an alias, do it.
  61.  * Repeat a maximum of 50 times.
  62.  */
  63. static int aleft;
  64. extern int hleft;
  65. void
  66. alias(lex)
  67.     register struct wordent *lex;
  68. {
  69.     jmp_buf osetexit;
  70.  
  71.     aleft = ALEFT;
  72.     hleft = HLEFT;
  73.     getexit(osetexit);
  74.     (void) setexit();
  75.     if (haderr) {
  76.     resexit(osetexit);
  77.     reset();
  78.     }
  79.     if (--aleft == 0)
  80.     stderror(ERR_ALIASLOOP);
  81.     asyntax(lex->next, lex);
  82.     resexit(osetexit);
  83. }
  84.  
  85. static void
  86. asyntax(p1, p2)
  87.     register struct wordent *p1, *p2;
  88. {
  89.     while (p1 != p2)
  90.     if (any(";&\n", p1->word[0]))
  91.         p1 = p1->next;
  92.     else {
  93.         asyn0(p1, p2);
  94.         return;
  95.     }
  96. }
  97.  
  98. static void
  99. asyn0(p1, p2)
  100.     struct wordent *p1;
  101.     register struct wordent *p2;
  102. {
  103.     register struct wordent *p;
  104.     register int l = 0;
  105.  
  106.     for (p = p1; p != p2; p = p->next)
  107.     switch (p->word[0]) {
  108.  
  109.     case '(':
  110.         l++;
  111.         continue;
  112.  
  113.     case ')':
  114.         l--;
  115.         if (l < 0)
  116.         stderror(ERR_TOOMANYRP);
  117.         continue;
  118.  
  119.     case '>':
  120.         if (p->next != p2 && eq(p->next->word, STRand))
  121.         p = p->next;
  122.         continue;
  123.  
  124.     case '&':
  125.     case '|':
  126.     case ';':
  127.     case '\n':
  128.         if (l != 0)
  129.         continue;
  130.         asyn3(p1, p);
  131.         asyntax(p->next, p2);
  132.         return;
  133.  
  134.     default:
  135.         break;
  136.     }
  137.     if (l == 0)
  138.     asyn3(p1, p2);
  139. }
  140.  
  141. static void
  142. asyn3(p1, p2)
  143.     struct wordent *p1;
  144.     register struct wordent *p2;
  145. {
  146.     register struct varent *ap;
  147.     struct wordent alout;
  148.     register bool redid;
  149.  
  150.     if (p1 == p2)
  151.     return;
  152.     if (p1->word[0] == '(') {
  153.     for (p2 = p2->prev; p2->word[0] != ')'; p2 = p2->prev)
  154.         if (p2 == p1)
  155.         return;
  156.     if (p2 == p1->next)
  157.         return;
  158.     asyn0(p1->next, p2);
  159.     return;
  160.     }
  161.     ap = adrof1(p1->word, &aliases);
  162.     if (ap == 0)
  163.     return;
  164.     alhistp = p1->prev;
  165.     alhistt = p2;
  166.     alvec = ap->vec;
  167.     redid = lex(&alout);
  168.     alhistp = alhistt = 0;
  169.     alvec = 0;
  170.     if (seterr) {
  171.     freelex(&alout);
  172.     stderror(ERR_OLD);
  173.     }
  174.     if (p1->word[0] && eq(p1->word, alout.next->word)) {
  175.     Char   *cp = alout.next->word;
  176.  
  177.     alout.next->word = Strspl(STRQNULL, cp);
  178.     xfree((ptr_t) cp);
  179.     }
  180.     p1 = freenod(p1, redid ? p2 : p1->next);
  181.     if (alout.next != &alout) {
  182.     p1->next->prev = alout.prev->prev;
  183.     alout.prev->prev->next = p1->next;
  184.     alout.next->prev = p1;
  185.     p1->next = alout.next;
  186.     xfree((ptr_t) alout.prev->word);
  187.     xfree((ptr_t) (alout.prev));
  188.     }
  189.     reset();            /* throw! */
  190. }
  191.  
  192. static struct wordent *
  193. freenod(p1, p2)
  194.     register struct wordent *p1, *p2;
  195. {
  196.     register struct wordent *retp = p1->prev;
  197.  
  198.     while (p1 != p2) {
  199.     xfree((ptr_t) p1->word);
  200.     p1 = p1->next;
  201.     xfree((ptr_t) (p1->prev));
  202.     }
  203.     retp->next = p2;
  204.     p2->prev = retp;
  205.     return (retp);
  206. }
  207.  
  208. #define    P_HERE    1
  209. #define    P_IN    2
  210. #define    P_OUT    4
  211. #define    P_DIAG    8
  212.  
  213. /*
  214.  * syntax
  215.  *    empty
  216.  *    syn0
  217.  */
  218. struct command *
  219. syntax(p1, p2, flags)
  220.     register struct wordent *p1, *p2;
  221.     int     flags;
  222. {
  223.  
  224.     while (p1 != p2)
  225.     if (any(";&\n", p1->word[0]))
  226.         p1 = p1->next;
  227.     else
  228.         return (syn0(p1, p2, flags));
  229.     return (0);
  230. }
  231.  
  232. /*
  233.  * syn0
  234.  *    syn1
  235.  *    syn1 & syntax
  236.  */
  237. static struct command *
  238. syn0(p1, p2, flags)
  239.     struct wordent *p1, *p2;
  240.     int     flags;
  241. {
  242.     register struct wordent *p;
  243.     register struct command *t, *t1;
  244.     int     l;
  245.  
  246.     l = 0;
  247.     for (p = p1; p != p2; p = p->next)
  248.     switch (p->word[0]) {
  249.  
  250.     case '(':
  251.         l++;
  252.         continue;
  253.  
  254.     case ')':
  255.         l--;
  256.         if (l < 0)
  257.         seterror(ERR_TOOMANYRP);
  258.         continue;
  259.  
  260.     case '|':
  261.         if (p->word[1] == '|')
  262.         continue;
  263.         /* fall into ... */
  264.  
  265.     case '>':
  266.         if (p->next != p2 && eq(p->next->word, STRand))
  267.         p = p->next;
  268.         continue;
  269.  
  270.     case '&':
  271.         if (l != 0)
  272.         break;
  273.         if (p->word[1] == '&')
  274.         continue;
  275.         t1 = syn1(p1, p, flags);
  276.         if (t1->t_dtyp == NODE_LIST ||
  277.         t1->t_dtyp == NODE_AND ||
  278.         t1->t_dtyp == NODE_OR) {
  279.         t = (struct command *) xcalloc(1, sizeof(*t));
  280.         t->t_dtyp = NODE_PAREN;
  281.         t->t_dflg = F_AMPERSAND | F_NOINTERRUPT;
  282.         t->t_dspr = t1;
  283.         t1 = t;
  284.         }
  285.         else
  286.         t1->t_dflg |= F_AMPERSAND | F_NOINTERRUPT;
  287.         t = (struct command *) xcalloc(1, sizeof(*t));
  288.         t->t_dtyp = NODE_LIST;
  289.         t->t_dflg = 0;
  290.         t->t_dcar = t1;
  291.         t->t_dcdr = syntax(p, p2, flags);
  292.         return (t);
  293.     default:
  294.         break;
  295.     }
  296.     if (l == 0)
  297.     return (syn1(p1, p2, flags));
  298.     seterror(ERR_TOOMANYLP);
  299.     return (0);
  300. }
  301.  
  302. /*
  303.  * syn1
  304.  *    syn1a
  305.  *    syn1a ; syntax
  306.  */
  307. static struct command *
  308. syn1(p1, p2, flags)
  309.     struct wordent *p1, *p2;
  310.     int     flags;
  311. {
  312.     register struct wordent *p;
  313.     register struct command *t;
  314.     int     l;
  315.  
  316.     l = 0;
  317.     for (p = p1; p != p2; p = p->next)
  318.     switch (p->word[0]) {
  319.  
  320.     case '(':
  321.         l++;
  322.         continue;
  323.  
  324.     case ')':
  325.         l--;
  326.         continue;
  327.  
  328.     case ';':
  329.     case '\n':
  330.         if (l != 0)
  331.         break;
  332.         t = (struct command *) xcalloc(1, sizeof(*t));
  333.         t->t_dtyp = NODE_LIST;
  334.         t->t_dcar = syn1a(p1, p, flags);
  335.         t->t_dcdr = syntax(p->next, p2, flags);
  336.         if (t->t_dcdr == 0)
  337.         t->t_dcdr = t->t_dcar, t->t_dcar = 0;
  338.         return (t);
  339.  
  340.     default:
  341.         break;
  342.     }
  343.     return (syn1a(p1, p2, flags));
  344. }
  345.  
  346. /*
  347.  * syn1a
  348.  *    syn1b
  349.  *    syn1b || syn1a
  350.  */
  351. static struct command *
  352. syn1a(p1, p2, flags)
  353.     struct wordent *p1, *p2;
  354.     int     flags;
  355. {
  356.     register struct wordent *p;
  357.     register struct command *t;
  358.     register int l = 0;
  359.  
  360.     for (p = p1; p != p2; p = p->next)
  361.     switch (p->word[0]) {
  362.  
  363.     case '(':
  364.         l++;
  365.         continue;
  366.  
  367.     case ')':
  368.         l--;
  369.         continue;
  370.  
  371.     case '|':
  372.         if (p->word[1] != '|')
  373.         continue;
  374.         if (l == 0) {
  375.         t = (struct command *) xcalloc(1, sizeof(*t));
  376.         t->t_dtyp = NODE_OR;
  377.         t->t_dcar = syn1b(p1, p, flags);
  378.         t->t_dcdr = syn1a(p->next, p2, flags);
  379.         t->t_dflg = 0;
  380.         return (t);
  381.         }
  382.         continue;
  383.  
  384.     default:
  385.         break;
  386.     }
  387.     return (syn1b(p1, p2, flags));
  388. }
  389.  
  390. /*
  391.  * syn1b
  392.  *    syn2
  393.  *    syn2 && syn1b
  394.  */
  395. static struct command *
  396. syn1b(p1, p2, flags)
  397.     struct wordent *p1, *p2;
  398.     int     flags;
  399. {
  400.     register struct wordent *p;
  401.     register struct command *t;
  402.     register int l = 0;
  403.  
  404.     for (p = p1; p != p2; p = p->next)
  405.     switch (p->word[0]) {
  406.  
  407.     case '(':
  408.         l++;
  409.         continue;
  410.  
  411.     case ')':
  412.         l--;
  413.         continue;
  414.  
  415.     case '&':
  416.         if (p->word[1] == '&' && l == 0) {
  417.         t = (struct command *) xcalloc(1, sizeof(*t));
  418.         t->t_dtyp = NODE_AND;
  419.         t->t_dcar = syn2(p1, p, flags);
  420.         t->t_dcdr = syn1b(p->next, p2, flags);
  421.         t->t_dflg = 0;
  422.         return (t);
  423.         }
  424.         continue;
  425.  
  426.     default:
  427.         break;
  428.     }
  429.     return (syn2(p1, p2, flags));
  430. }
  431.  
  432. /*
  433.  * syn2
  434.  *    syn3
  435.  *    syn3 | syn2
  436.  *    syn3 |& syn2
  437.  */
  438. static struct command *
  439. syn2(p1, p2, flags)
  440.     struct wordent *p1, *p2;
  441.     int     flags;
  442. {
  443.     register struct wordent *p, *pn;
  444.     register struct command *t;
  445.     register int l = 0;
  446.     int     f;
  447.  
  448.     for (p = p1; p != p2; p = p->next)
  449.     switch (p->word[0]) {
  450.  
  451.     case '(':
  452.         l++;
  453.         continue;
  454.  
  455.     case ')':
  456.         l--;
  457.         continue;
  458.  
  459.     case '|':
  460.         if (l != 0)
  461.         continue;
  462.         t = (struct command *) xcalloc(1, sizeof(*t));
  463.         f = flags | P_OUT;
  464.         pn = p->next;
  465.         if (pn != p2 && pn->word[0] == '&') {
  466.         f |= P_DIAG;
  467.         t->t_dflg |= F_STDERR;
  468.         }
  469.         t->t_dtyp = NODE_PIPE;
  470.         t->t_dcar = syn3(p1, p, f);
  471.         if (pn != p2 && pn->word[0] == '&')
  472.         p = pn;
  473.         t->t_dcdr = syn2(p->next, p2, flags | P_IN);
  474.         return (t);
  475.  
  476.     default:
  477.         break;
  478.     }
  479.     return (syn3(p1, p2, flags));
  480. }
  481.  
  482. static char RELPAR[] = {'<', '>', '(', ')', '\0'};
  483.  
  484. /*
  485.  * syn3
  486.  *    ( syn0 ) [ < in  ] [ > out ]
  487.  *    word word* [ < in ] [ > out ]
  488.  *    KEYWORD ( word* ) word* [ < in ] [ > out ]
  489.  *
  490.  *    KEYWORD = (@ exit foreach if set switch test while)
  491.  */
  492. static struct command *
  493. syn3(p1, p2, flags)
  494.     struct wordent *p1, *p2;
  495.     int     flags;
  496. {
  497.     register struct wordent *p;
  498.     struct wordent *lp, *rp;
  499.     register struct command *t;
  500.     register int l;
  501.     Char  **av;
  502.     int     n, c;
  503.     bool    specp = 0;
  504.  
  505.     if (p1 != p2) {
  506.     p = p1;
  507. again:
  508.     switch (srchx(p->word)) {
  509.  
  510.     case T_ELSE:
  511.         p = p->next;
  512.         if (p != p2)
  513.         goto again;
  514.         break;
  515.  
  516.     case T_EXIT:
  517.     case T_FOREACH:
  518.     case T_IF:
  519.     case T_LET:
  520.     case T_SET:
  521.     case T_SWITCH:
  522.     case T_WHILE:
  523.         specp = 1;
  524.         break;
  525.     default:
  526.         break;
  527.     }
  528.     }
  529.     n = 0;
  530.     l = 0;
  531.     for (p = p1; p != p2; p = p->next)
  532.     switch (p->word[0]) {
  533.  
  534.     case '(':
  535.         if (specp)
  536.         n++;
  537.         l++;
  538.         continue;
  539.  
  540.     case ')':
  541.         if (specp)
  542.         n++;
  543.         l--;
  544.         continue;
  545.  
  546.     case '>':
  547.     case '<':
  548.         if (l != 0) {
  549.         if (specp)
  550.             n++;
  551.         continue;
  552.         }
  553.         if (p->next == p2)
  554.         continue;
  555.         if (any(RELPAR, p->next->word[0]))
  556.         continue;
  557.         n--;
  558.         continue;
  559.  
  560.     default:
  561.         if (!specp && l != 0)
  562.         continue;
  563.         n++;
  564.         continue;
  565.     }
  566.     if (n < 0)
  567.     n = 0;
  568.     t = (struct command *) xcalloc(1, sizeof(*t));
  569.     av = (Char **) xcalloc((size_t) (n + 1), sizeof(Char **));
  570.     t->t_dcom = av;
  571.     n = 0;
  572.     if (p2->word[0] == ')')
  573.     t->t_dflg = F_NOFORK;
  574.     lp = 0;
  575.     rp = 0;
  576.     l = 0;
  577.     for (p = p1; p != p2; p = p->next) {
  578.     c = p->word[0];
  579.     switch (c) {
  580.  
  581.     case '(':
  582.         if (l == 0) {
  583.         if (lp != 0 && !specp)
  584.             seterror(ERR_BADPLP);
  585.         lp = p->next;
  586.         }
  587.         l++;
  588.         goto savep;
  589.  
  590.     case ')':
  591.         l--;
  592.         if (l == 0)
  593.         rp = p;
  594.         goto savep;
  595.  
  596.     case '>':
  597.         if (l != 0)
  598.         goto savep;
  599.         if (p->word[1] == '>')
  600.         t->t_dflg |= F_APPEND;
  601.         if (p->next != p2 && eq(p->next->word, STRand)) {
  602.         t->t_dflg |= F_STDERR, p = p->next;
  603.         if (flags & (P_OUT | P_DIAG)) {
  604.             seterror(ERR_OUTRED);
  605.             continue;
  606.         }
  607.         }
  608.         if (p->next != p2 && eq(p->next->word, STRbang))
  609.         t->t_dflg |= F_OVERWRITE, p = p->next;
  610.         if (p->next == p2) {
  611.         seterror(ERR_MISRED);
  612.         continue;
  613.         }
  614.         p = p->next;
  615.         if (any(RELPAR, p->word[0])) {
  616.         seterror(ERR_MISRED);
  617.         continue;
  618.         }
  619.         if (((flags & P_OUT) && (flags & P_DIAG) == 0) || t->t_drit)
  620.         seterror(ERR_OUTRED);
  621.         else
  622.         t->t_drit = Strsave(p->word);
  623.         continue;
  624.  
  625.     case '<':
  626.         if (l != 0)
  627.         goto savep;
  628.         if (p->word[1] == '<')
  629.         t->t_dflg |= F_READ;
  630.         if (p->next == p2) {
  631.         seterror(ERR_MISRED);
  632.         continue;
  633.         }
  634.         p = p->next;
  635.         if (any(RELPAR, p->word[0])) {
  636.         seterror(ERR_MISRED);
  637.         continue;
  638.         }
  639.         if ((flags & P_HERE) && (t->t_dflg & F_READ))
  640.         seterror(ERR_REDPAR);
  641.         else if ((flags & P_IN) || t->t_dlef)
  642.         seterror(ERR_INRED);
  643.         else
  644.         t->t_dlef = Strsave(p->word);
  645.         continue;
  646.  
  647.     savep:
  648.         if (!specp)
  649.         continue;
  650.     default:
  651.         if (l != 0 && !specp)
  652.         continue;
  653.         if (seterr == 0)
  654.         av[n] = Strsave(p->word);
  655.         n++;
  656.         continue;
  657.     }
  658.     }
  659.     if (lp != 0 && !specp) {
  660.     if (n != 0)
  661.         seterror(ERR_BADPLPS);
  662.     t->t_dtyp = NODE_PAREN;
  663.     t->t_dspr = syn0(lp, rp, P_HERE);
  664.     }
  665.     else {
  666.     if (n == 0)
  667.         seterror(ERR_NULLCOM);
  668.     t->t_dtyp = NODE_COMMAND;
  669.     }
  670.     return (t);
  671. }
  672.  
  673. void
  674. freesyn(t)
  675.     register struct command *t;
  676. {
  677.     register Char **v;
  678.  
  679.     if (t == 0)
  680.     return;
  681.     switch (t->t_dtyp) {
  682.  
  683.     case NODE_COMMAND:
  684.     for (v = t->t_dcom; *v; v++)
  685.         xfree((ptr_t) * v);
  686.     xfree((ptr_t) (t->t_dcom));
  687.     xfree((ptr_t) t->t_dlef);
  688.     xfree((ptr_t) t->t_drit);
  689.     break;
  690.     case NODE_PAREN:
  691.     freesyn(t->t_dspr);
  692.     xfree((ptr_t) t->t_dlef);
  693.     xfree((ptr_t) t->t_drit);
  694.     break;
  695.  
  696.     case NODE_AND:
  697.     case NODE_OR:
  698.     case NODE_PIPE:
  699.     case NODE_LIST:
  700.     freesyn(t->t_dcar), freesyn(t->t_dcdr);
  701.     break;
  702.     default:
  703.     break;
  704.     }
  705.     xfree((ptr_t) t);
  706. }
  707.